package com.service;

import static com.def.GenericDef.E_XPTOOLOPE_INVALID_INPUT;
import static com.def.GenericDef.RETURN_CODE_OK;
import static com.def.GenericDef.RETURN_CODE_SET_ERROR;
import static com.def.GenericDef.RETURN_CODE_UNKNOWN;
import static com.def.GenericDef.RETURN_MESG_OK;
import static com.def.GenericDef.TRX_OUT;
import static com.def.GenericDef.T_XPTOOLCHK;
import static com.def.GenericDef._NORMAL;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.dao.IBisMItemDao;
import com.dao.IBisMLabelDao;
import com.dao.IRetToolChkDao;
import com.icim.service.ICIMBaseService;
import com.model.Bis_m_item;
import com.model.Bis_m_label;
import com.model.Ret_tool_chk;
import com.tx.Xptoolchk.XptoolchkI;
import com.tx.Xptoolchk.XptoolchkIA;
import com.tx.Xptoolchk.XptoolchkO;
import com.tx.Xptoolchk.XptoolchkOA;
import com.util.GUIDGenerator;
import com.util.GUIDGenerator16;
import com.util.MqOpe;
import com.util.Util;

@Scope("prototype")
@Service("XptoolchkService")
public class XptoolchkService extends ICIMBaseService{
	private static Logger logger = Logger.getLogger(XptoolchkService.class);
	private static String TX_NAME = T_XPTOOLCHK;
	
	private final char IN_FIND_M_ITEM_BY_TOOL ='F';
	private final char IN_ADD_CHK_RECORE ='C';
	private final char IN_UPDATE_CHK_RECORE ='U';
	private final char IN_QUERY_CHK_RECORE ='Q';
	
	
	private final String REP_UNIT_TOOL = "T";
	private final String DATA_PAT_TOOL_CHECK = "01";
	
	private XptoolchkI inTrx ;
	private XptoolchkO outTrx;
	private MqOpe mqOpe;
	
	private String gszMsgBuf;	
	private Timestamp gEvtTimestamp;
	
	@Autowired
	private IBisMLabelDao bisMLabelDao;
	@Autowired
	private IBisMItemDao bisMItemDao;
	@Autowired
	private IRetToolChkDao retToolChkDao;
	
	
	public String subMainProc(String strInMsg) {
		Session session = bisMLabelDao.getCrSession();

		long rtnCode = _NORMAL;
		String outMsg = null;
		gszMsgBuf = "";
		gEvtTimestamp = Util.getCurrentTimestamp();
		inTrx = new XptoolchkI();
		outTrx = new XptoolchkO();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setType_id(TRX_OUT);
		outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));
		mqOpe = new MqOpe();
		
    	try{
    		inTrx = (XptoolchkI) mqOpe.inStr2Obj(strInMsg, inTrx);
			logger.info("InTrx is " + strInMsg);
			
			rtnCode = subMainProc2(inTrx.getAction_flg().toCharArray()[0]);
			if (rtnCode != _NORMAL) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				outTrx.setRtn_code(String.valueOf(rtnCode));
				outTrx.setRtn_mesg(gszMsgBuf);
			} else {
				outTrx.setRtn_code(String.valueOf(RETURN_CODE_OK));
				outTrx.setRtn_mesg(RETURN_MESG_OK);
				session.flush();
			}
    	}catch(Exception ex){
    		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    		outTrx.setRtn_mesg(ex.toString());
    		outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
    		logger.error(Util.stackTraceToString(ex));
    	}finally{
    		outMsg = mqOpe.obj2Str(outTrx);
    		return outMsg; 
    	}
	}
	
	
	/**
	 * Real action type
	 * @param actionType
	 * @return
	 */
	private long subMainProc2(char actionType) {
		long lRc = _NORMAL;
		switch (actionType)
		{
			case IN_FIND_M_ITEM_BY_TOOL: {
				lRc = getToolChkList();
				break;
			}
			case IN_ADD_CHK_RECORE:{
				addToolCheckRecord();
				break;
			}
			case IN_UPDATE_CHK_RECORE:{
				updateToolCheckRecord();
				break;
			}
			case IN_QUERY_CHK_RECORE:{
				getToolCheckRecordList();
				break;
			}			
			default:{
				gszMsgBuf = "Invalide type input: [" + actionType + "]";
				return E_XPTOOLOPE_INVALID_INPUT;
			}
		}
		
		return lRc;
	}
	
	/**
	 * Get m_item list by tool
	 * @return List<Bis_m_item>  
	 */
	private List<Bis_m_item> getMLabelList(String toolId){
		List<Bis_m_item> bis_m_itemList  = new ArrayList<Bis_m_item>();
		String strHqlGetMItem="from Bis_m_item a where id.tool_id_fk = ? and id.rep_unit_fk = ? and id.data_pat_fk = ? and id.mes_id_fk =? ";
		
		String strHqlGetMLabel="from Bis_m_label a where id.tool_id_fk = ? and id.rep_unit = ? and id.data_pat = ? ";
		List<Bis_m_label> bis_m_labelList = bisMLabelDao.find(strHqlGetMLabel, 
				new String[]{toolId, REP_UNIT_TOOL, DATA_PAT_TOOL_CHECK });
		
		if(!bis_m_labelList.isEmpty()){
			for(Bis_m_label m : bis_m_labelList){
				List<Bis_m_item> bis_m_itemListNew = new ArrayList<Bis_m_item>();
				bis_m_itemListNew = bisMItemDao.find(strHqlGetMItem, 
						new String[]{m.getId().getTool_id_fk(),
						m.getId().getRep_unit(),
						m.getId().getData_pat(),
						m.getId().getMes_id_fk()});
				
				if(!bis_m_itemListNew.isEmpty()){
					bis_m_itemList.addAll(bis_m_itemListNew);
				}
			}	
		} 
		
		return bis_m_itemList;
	}
	
	/**
	 * Query m_item list by tool.
	 * @return
	 */
	private long getToolChkList(){
		long lRc = _NORMAL; 
		Bis_m_label bis_m_label = new Bis_m_label();
		List<Bis_m_item> bis_m_itemList  = new ArrayList<Bis_m_item>();

		bis_m_itemList = this.getMLabelList(inTrx.getTool_id());
		if(!bis_m_itemList.isEmpty()){
			outTrx.setTool_id(bis_m_itemList.get(0).getId().getTool_id_fk());
			outTrx.setRep_unit(bis_m_itemList.get(0).getId().getRep_unit_fk());
			outTrx.setData_pat(bis_m_itemList.get(0).getId().getData_pat_fk());
			outTrx.setMes_id(bis_m_itemList.get(0).getId().getMes_id_fk());
			outTrx.setData_cnt(bis_m_itemList.size());
			
			List<XptoolchkOA> oary = new ArrayList<XptoolchkOA>();
			for(int x=0; x < bis_m_itemList.size(); x++){
				XptoolchkOA xptoolchkOA = new XptoolchkOA();
				xptoolchkOA.setTool_id(bis_m_itemList.get(x).getId().getTool_id_fk());
				xptoolchkOA.setRep_unit_id(bis_m_itemList.get(x).getId().getRep_unit_fk());
				xptoolchkOA.setData_pat_id(bis_m_itemList.get(x).getId().getData_pat_fk());
				xptoolchkOA.setMes_id(bis_m_itemList.get(x).getId().getMes_id_fk());
				xptoolchkOA.setData_id(bis_m_itemList.get(x).getId().getData_id());
				
				xptoolchkOA.setData_group(bis_m_itemList.get(x).getData_group());
				xptoolchkOA.setData_dsc(bis_m_itemList.get(x).getData_dsc());
				xptoolchkOA.setData_attr(bis_m_itemList.get(x).getData_attr());
				xptoolchkOA.setOpi_data_flg(bis_m_itemList.get(x).getOpi_data_flg()); //TODO For what? m_label already has it
				xptoolchkOA.setSpc_mode(bis_m_itemList.get(x).getSpc_mode());
				
				xptoolchkOA.setSpec_chk_flg(bis_m_itemList.get(x).getSpec_chk_flg());
				if(null != bis_m_itemList.get(x).getL_spec()){
					xptoolchkOA.setSpec_chk_l(bis_m_itemList.get(x).getL_spec().toString());
				}
				if(null != bis_m_itemList.get(x).getU_spec()){
					xptoolchkOA.setSpec_chk_u(bis_m_itemList.get(x).getU_spec().toString());
				}
				
				
				oary.add(xptoolchkOA);
			}
			outTrx.setOary(oary);
		}else{
			outTrx.setData_cnt(0);
		}

		return lRc;
	}
	
	/**
	 * Tool check process
	 * @return
	 */
	private long addToolCheckRecord(){
		long lRc = _NORMAL;
		
		String curUUID = GUIDGenerator16.generateGUID(16);
		
		if(!inTrx.getIary().isEmpty()){
			for(XptoolchkIA iItem : inTrx.getIary()){
				Ret_tool_chk ret_tool_chk = new Ret_tool_chk();
				ret_tool_chk.setChk_seq_id(GUIDGenerator.javaGUID());
				ret_tool_chk.setChk_evt_seq_id(curUUID);
				ret_tool_chk.setTool_id_fk(iItem.getTool_id());
				ret_tool_chk.setRep_unit_fk(iItem.getRep_unit_id());
				ret_tool_chk.setData_pat_fk(iItem.getData_pat_id());
				ret_tool_chk.setMes_id_fk(iItem.getMes_id());
				ret_tool_chk.setData_id(iItem.getData_id());
				
				ret_tool_chk.setData_group_fk(iItem.getData_group());
				ret_tool_chk.setData_dsc(iItem.getData_dsc());
				ret_tool_chk.setData_value(iItem.getData_value());
				if( !Util.isSpaceCheck(iItem.getSpec_chk_l()) ){
					ret_tool_chk.setL_spec_fk(Double.valueOf(iItem.getSpec_chk_l()));
				}
				if( !Util.isSpaceCheck(iItem.getSpec_chk_u())){
					ret_tool_chk.setU_spec_fk(Double.valueOf(iItem.getSpec_chk_u()));
				}
				ret_tool_chk.setEvt_usr(inTrx.getEvt_usr());
				ret_tool_chk.setEvt_timestamp(gEvtTimestamp); 
				ret_tool_chk.setAc_pm_note(iItem.getAc_pm_note());
				ret_tool_chk.setOcap_id(iItem.getOcap_id());
				
				retToolChkDao.save(ret_tool_chk);
			}
		}
		
		return lRc;
	}

	/**
	 * Update tool check records
	 * @return
	 */
	private long updateToolCheckRecord(){
		long lRc = _NORMAL;
//		Bis_m_label bis_m_label = new Bis_m_label();
//		
////		bis_m_label = checkMLabel();
////		if(null == bis_m_label){
////			return E_BIS_M_LABEL + E_READ_NOT_FOUND;
////		}
//		
//		if(!inTrx.getIary().isEmpty()){
//			for(XptoolchkIA iItem : inTrx.getIary()){
//				Ret_tool_chk ret_tool_chk = new Ret_tool_chk();
//				ret_tool_chk = retToolChkDao.get(iItem.getChk_seq_id());
//				ret_tool_chk.setData_value(iItem.getDate_value());
//				retToolChkDao.update(ret_tool_chk);
//			}
//		}
		return lRc;
	}
	
	/**
	 * Query tool check record
	 * By tool and time range
	 * @return
	 */
	private long getToolCheckRecordList(){
		long lRc = _NORMAL;
		
//		outTrx.setTool_id(inTrx.getTool_id());
//		outTrx.setRep_unit(inTrx.getRep_unit());
//		outTrx.setData_pat(inTrx.getData_pat());
//		outTrx.setMes_id(inTrx.getMes_id());
//		
//		List<Ret_tool_chk> ret_tool_chkList = new ArrayList<Ret_tool_chk>(); 
//		ret_tool_chkList = retToolChkDao.getToolCheckRecordList(inTrx.getTool_id(), inTrx.getRep_unit(), inTrx.getData_pat(), inTrx.getMes_id(),
//				inTrx.getQuery_begin_time(), inTrx.getQuery_end_time());
//		outTrx.setData_cnt(ret_tool_chkList.size());
//		if(0<ret_tool_chkList.size()){
//			for(Ret_tool_chk item : ret_tool_chkList){
//				XptoolchkOA xptoolchkOA = new XptoolchkOA();
//				xptoolchkOA.setChk_seq_id(item.getChk_seq_id());
//				xptoolchkOA.setDate_id(item.getData_id());
//				xptoolchkOA.setDate_group(item.getData_id());
//				xptoolchkOA.setDate_dsc(item.getData_dsc());
////				xptoolchkOA.setDate_attr();
//				
//			}
//		}
 
		return lRc;
	}
}
